package com.example.drools.spring.yc.core.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import com.example.drools.spring.core.helper.RuleTransformHelper;
import com.example.drools.spring.entity.DroolModel;
import com.example.drools.spring.entity.KieResoure;
import com.example.drools.spring.yc.core.YcAgendaFilter;
import com.example.drools.spring.yc.core.YcRuleEngine;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.drools.compiler.kie.builder.impl.InternalKieModule;
import org.drools.compiler.kie.builder.impl.KieContainerImpl;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.FactHandle;
import org.springframework.stereotype.Service;

/**
 * @author ddsyw
 * @version 1.0
 * @date 2021/12/31 10:01 上午
 */
@Slf4j
@Service
public class YcRuleEngineServiceImpl implements YcRuleEngine {

    @Resource
    private KieContainerImpl kieContainer;
    @Resource
    private KieFileSystem kieFileSystem;
    @Resource
    private KieSession kieSession;

    @Override
    public void executeRuleEngine(Object drool) {
        executeRuleEngine(drool);
    }

    @Override
    public void executeRuleEngine(Object... drool) {
        executeRuleEngine(null, drool);
    }

    @Override
    public void executeRuleEngine(YcAgendaFilter ycAgendaFilter, Object... drools) {
        if (Objects.isNull(drools)) {
            return;
        }
        List<FactHandle> handleList = new ArrayList<>();
        try {
            for (Object obj : drools) {
                if (Objects.nonNull(obj)) {
                    FactHandle factHandle = kieSession.insert(obj);
                    handleList.add(factHandle);
                }
            }
            if (Objects.nonNull(ycAgendaFilter)) {
                kieSession.fireAllRules(ycAgendaFilter);
            } else {
                kieSession.fireAllRules();
            }
            handleList.forEach(factHandle -> kieSession.delete(factHandle));
        } catch (Exception e) {
            log.error("execute rule error:{}", ExceptionUtil.getMessage(e));
        }
    }

    @Override
    public void initEngine() {

    }

    @Override
    public void refreshEnginRule(DroolModel droolModel) {
        if (Objects.isNull(droolModel)) {
            return;
        }
        Map<String, KieResoure> kieResoureMap = RuleTransformHelper.transFromDroolModel(
            Arrays.asList(droolModel));
        if (CollectionUtil.isEmpty(kieResoureMap)) {
            return;
        }
        kieResoureMap.forEach((key, val) -> {
            kieFileSystem.write(key, val.getResoure());
        });
        KieBuilder kieBuilder = KieServices.Factory.get().newKieBuilder(kieFileSystem);
        kieBuilder.buildAll();
        kieContainer.updateToKieModule((InternalKieModule) kieBuilder.getKieModule());
    }
}
